package main

import (
	"fmt"
	"sync"
)

func main() {
	closedStupid()
	closedRange()
	fmt.Println("--------")
	square()
}

func closedStupid() {
	s := make(chan int)

	go func() {
		for i := 1; i <= 5; i++ {
			s <- i
		}
		close(s)
	}()

	// main goroutine
	for {
		j, ok := <-s
		if !ok {
			break
		}
		fmt.Printf("%d ", j)
	}
	fmt.Println("")
}

func closedRange() {
	s := make(chan int)

	go func() {
		for i := 1; i <= 5; i++ {
			s <- i
		}
		close(s)
	}()

	// main goroutine
	for j := range s {
		fmt.Printf("%d ", j)
	}
	fmt.Println("")
}

func square() {
	il := []int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
	ch := make(chan map[int]int)
	var wg sync.WaitGroup // WaitGroup apply in non-cached channel

	for _, i := range il {
		wg.Add(1) //before worker
		//worker
		go func(i int) {
			defer wg.Done() // wg -1
			ch <- map[int]int{i: i * i}
		}(i)
	}

	//closer
	go func() {
		wg.Wait()
		close(ch)
	}()

	for m := range ch {
		for k, v := range m {
			fmt.Printf("%d^2 = %d\n", k, v)
		}
	}
}
